<template>
  <div id="webgl-container" ref="containerRef" class="webgl-container">
    <canvas id="webgl" class="webgl"/>
  </div>
</template>

<script setup>
import * as THREE from 'three'
import { ref, onMounted, onUnmounted } from 'vue'

import { useThree } from '@/hooks/use-three-hook.js'

const containerRef = ref(null)
const { scene, camera, addAnimationCallback } = useThree()

const textureLoader = new THREE.TextureLoader()
const particleTexture = textureLoader.load('/textures/particles/raindrop-4.png')
particleTexture.colorSpace = THREE.SRGBColorSpace

// 雨滴粒子系统
let rainParticles = null
let rainGeometry = null
let rainMaterial = null

// 创建雨滴
const createRain = () => {
  // 创建雨滴几何体
  const count = 10000
  rainGeometry = new THREE.BufferGeometry()

  const positions = new Float32Array(count * 3)
  const velocities = new Float32Array(count * 3)

  for (let i = 0; i < count * 3; i += 3) {
    // 随机位置
    positions[i] = (Math.random() - 0.5) * 100 // x
    positions[i + 1] = Math.random() * 50 + 10 // y
    positions[i + 2] = (Math.random() - 0.5) * 100 // z

    // 随机速度
    velocities[i] = (Math.random() - 0.5) * 2 // x方向轻微扰动
    velocities[i + 1] = -(Math.random() * 10 + 10) // y方向下落速度
    velocities[i + 2] = (Math.random() - 0.5) * 2 // z方向轻微扰动
  }

  rainGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
  rainGeometry.setAttribute(
    'velocity',
    new THREE.BufferAttribute(velocities, 3)
  )

  // 创建雨滴材质
  rainMaterial = new THREE.PointsMaterial({
    // vertexColors: true, // 如果设置了顶点颜色
    // alphaMap: particleTexture,
    map: particleTexture,
    size: 0.3,
    sizeAttenuation: true,
    transparent: true,
    opacity: 0.8,
    depthWrite: false, // 避免深度冲突
    blending: THREE.AdditiveBlending // 添加混合模式使雨滴更亮
  })

  // 创建粒子系统
  rainParticles = new THREE.Points(rainGeometry, rainMaterial)
  scene.value.add(rainParticles)
}

// 更新雨滴动画
const updateRain = () => {
  if (!rainGeometry) return

  const positions = rainGeometry.attributes.position.array
  const velocities = rainGeometry.attributes.velocity.array

  for (let i = 0; i < positions.length; i += 3) {
    // 更新位置
    positions[i] += velocities[i] * 0.01
    positions[i + 1] += velocities[i + 1] * 0.01
    positions[i + 2] += velocities[i + 2] * 0.01

    // 如果雨滴落到地面以下，重新设置到顶部
    if (positions[i + 1] < -10) {
      positions[i] = (Math.random() - 0.5) * 100
      positions[i + 1] = Math.random() * 50 + 10
      positions[i + 2] = (Math.random() - 0.5) * 100
    }
  }

  rainGeometry.attributes.position.needsUpdate = true
}

// 初始化场景
const initScene = () => {
  // 设置相机位置
  camera.value.position.set(0, 10, 20)
  camera.value.lookAt(0, 0, 0)

  // 添加光源
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
  scene.value.add(ambientLight)

  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
  directionalLight.position.set(10, 20, 15)
  scene.value.add(directionalLight)

  // 创建地面
  const groundGeometry = new THREE.PlaneGeometry(100, 100)
  const groundMaterial = new THREE.MeshStandardMaterial({
    color: 0x333333,
    transparent: true,
    opacity: 0.5
  })
  const ground = new THREE.Mesh(groundGeometry, groundMaterial)
  ground.rotation.x = -Math.PI / 2
  ground.position.y = -10
  scene.value.add(ground)

  // 创建雨滴
  createRain()

  // 添加动画回调
  addAnimationCallback(updateRain)
}

onMounted(() => {
  if (containerRef.value) {
    // 初始化场景
    initScene()
  }
})

onUnmounted(() => {
  // 清理资源
  if (rainGeometry) {
    rainGeometry.dispose()
  }
  if (rainMaterial) {
    rainMaterial.dispose()
  }
})
</script>
